package com.ruoyi.system.task;


import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.config.MinioConfig;
import com.ruoyi.system.mapper.ByExportTaskMapper;
import com.ruoyi.system.service.impl.EsServiceImpl;
import com.ruoyi.system.domain.ByDb15;
import com.ruoyi.system.service.IEsService;
import com.ruoyi.system.utils.Md5Utils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.shaded.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;


import javax.activation.MimetypesFileTypeMap;
import java.io.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @author xu wei
 * @version 1.0
 * @date 2023/10/30
 * @since jdk-1.8
 */
@Slf4j
public class ByExportProcessorWrapper {

    private String author = null;
    //任务总数
//    private Integer taskMount = 0;

    //失败任务总数
    private AtomicInteger failCount = new AtomicInteger(0);
    //累积的任务总数
    private AtomicInteger allCount = new AtomicInteger(1);
    //成功任务总数
    private AtomicInteger successCount = new AtomicInteger(0);

    ByExportProcessor xmlProcessor = null;

//    @Autowired
//    private MinioConfig minioConfig;

//    @Autowired
//    private MinioClient client;

    @Value("${exportPath}")
    private String exportPath;

    public ByExportProcessorWrapper() {

    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }



    /**
     * @param userId       提交人
     * @param allCount     zongrenwush8u
     * @param failCount    失败数
     * @param successCount 成功数
     */
    public void init(String userId, AtomicInteger allCount, AtomicInteger successCount, AtomicInteger failCount) {
//        this.taskMount = taskMount;
        this.author = userId;
        this.allCount = allCount;
        this.successCount = successCount;
        this.failCount = failCount;
        xmlProcessor = new ByExportProcessor(userId);
    }

    public String getKeyword() {
        return this.keyword;
    }

    public String keyword;

    public String a101;

    public String a200;

    public String standardType;


    public String getA101() {
        return this.a101;
    }
    public String getA200() {
        return this.a200;
    }
    public String getStandardType() {
        return this.standardType;
    }

    public void setA101(String a101) {
        this.a101 = a101;
    }
    public void setA200(String a200) {
        this.a200 = a200;
    }
    public void setStandardType(String standardType) {
        this.standardType = standardType;
    }


    public int taskId;

    public int getTaskId() {
        return this.taskId;
    }

    public void setTaskId(int taskId) {
        this.taskId = taskId;
    }


    /**
     * 碎片化程序入口
     */
    void execute() {
        long st = System.currentTimeMillis();
        boolean processFrage = false;
        try {
            processFrage = this.process();
        } catch (Exception e) {
            e.printStackTrace();
            failCount.incrementAndGet();
            log.error("题录:{}导出失败-->{}", keyword, e.getMessage());
            log.error(e.getMessage(), e);
        }
        allCount.incrementAndGet();
        log.info("procssing-->{}/{}, cost {}s", allCount.get(), (System.currentTimeMillis() - st) / 1000);
        log.info("本次共导出: 其中成功：{}条，失败：{}条。;", successCount, failCount);
        afterImport();
        log.info("===================题录导出完成=============");

    }

    /**
     * 入库完成后续操作
     */
    void afterImport() {
        //上传完成  更新路径和状态
        try {
//            xmlProcessor.updateImportStatus(materialLibId);
        } catch (Exception e) {
            log.error("删除文件或者更新知识库异常{}", e.getMessage());
            log.error(e.getMessage(), e);
        } finally {
            ByExportTaskMapper byExportTaskMapper = SpringUtils.getBean(ByExportTaskMapper.class);
            byExportTaskMapper.doneTask(taskId,1);
        }
    }

    /**
     * 处理导入逻辑
     *
     * @throws Exception
     */
    public Boolean process() {
        log.info("===================begin to export【" + keyword + "】=============");
        log.info("===================begin to export【" + a101 + "】=============");
        log.info("===================begin to export【" + a200 + "】=============");
        log.info("===================begin to export【" + standardType + "】=============");
        //es查询集合
        EsServiceImpl esService = SpringUtils.getBean(EsServiceImpl.class);

        List<ByDb15> list = esService.searchAll(keyword,a101,a200,standardType);
        //执行导出操作
        doProcess(xmlProcessor, list, taskId);
        log.info("===================handle【" + keyword + "】done=============");
        return true;
    }

    /**
     * 处理碎片化的各个环节步骤
     *
     * @param xmlProcessor
     * @param list
     * @throws Exception
     */
    private void doProcess(ByExportProcessor xmlProcessor, List<ByDb15> list, int taskId) {
        //生成excel保存到指定路径 并上传到minio
        ExcelUtil<ByDb15> util = new ExcelUtil<ByDb15>(ByDb15.class);
        AjaxResult result = util.createExcel(list, "Standard数据");
        File file = null;
        InputStream inputStream = null;
        InputStream md5Stream = null;
        try {
            file = new File( RuoYiConfig.getDownloadPath() + result.get("msg").toString());


            inputStream = new FileInputStream(file);
            md5Stream = new FileInputStream(file);
            // 上传并返回新文件名称
            String fileName = FilenameUtils.getName(result.get("msg").toString());
            String md5 = Md5Utils.getFileMD5(md5Stream);

//            MimetypesFileTypeMap mimetypesFileTypeMaps = new MimetypesFileTypeMap();
//            String contentType = mimetypesFileTypeMaps.getContentType(result.get("msg").toString());
            MinioConfig minioConfig = SpringUtils.getBean(MinioConfig.class);
            MinioClient client = SpringUtils.getBean(MinioClient.class);
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.length(), -1)
                    .contentType("application/octet-stream")
                    .build();
            client.putObject(args);
            inputStream.close();
            md5Stream.close();

            String url = minioConfig.getReturnUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
            log.info("upload->{} to {}", file.getName(), url);

            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", fileName);
            ajax.put("newFileName", FileUtils.getName(fileName));
            ajax.put("originalFilename", file.getName());


            //更新文件路径
            ByExportTaskMapper byExportTaskMapper = SpringUtils.getBean(ByExportTaskMapper.class);
            byExportTaskMapper.updateFile(taskId,url);

        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("===================handle【" + result + "】fileresult=============");
        //更新数据库 任务状态和excel文件路径
//        xmlProcessor.handleMysql(taskId);
        successCount.incrementAndGet();
    }

}
